package com.skyMailbox.security;

import com.skyMailbox.webService.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.*;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.AuthenticationProvider;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class FakeAuthenticationProvider implements AuthenticationProvider {

    private static final Logger log = LoggerFactory.getLogger(FakeAuthenticationProvider.class);

    static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();

     static {
       AUTHORITIES.add(new GrantedAuthorityImpl("ROLE_USER"));
     }


    private static Map<String, String> ADMIN_USERS = new HashMap<String, String>(2) {{
        put("admin", "admin");
    }};

    @Override
    public boolean supports(Class authentication) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String userName = authentication.getName();
        log.debug("Autenticando a  ", userName);
        try {
            authentication = authenticateWS(authentication);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            return authentication;
        } catch (AuthenticationException e) {
            log.debug("Fallo al autenticar a el usuario ", new Object[]{userName, e.getMessage()});
            throw e;
        } catch (Exception e) {
            String message = "Excepvion inesperada";
            log.error(message, e);
            throw new AuthenticationServiceException(message, e);
        }
    }


    protected void additionalAuthenticationChecks(UserDetails arg0, UsernamePasswordAuthenticationToken arg1)
            throws AuthenticationException {
        // No se valida la contraseña porque ya se validó con LDAP
    }

    protected Authentication authenticateWS(Authentication authentication) {

        String principal = (String) authentication.getPrincipal();
        String password = (String) authentication.getCredentials();

        if (ADMIN_USERS.containsKey(principal) && ADMIN_USERS.get(principal).equals(password)) {
            return new UsernamePasswordAuthenticationToken(principal, password, new GrantedAuthorityImpl[]{new GrantedAuthorityImpl("ROLE_ADMIN")});
        }

        UPSAMService service = new UPSAMService();
        UPSAM movil = service.getUPSAMPort();
        Usuario usuario = movil.getUsuarioByLoginAndPassword(principal, password) ;

        if (usuario == null) {
            throw new UsernameNotFoundException("Usuario no encontrado");
        }

        if (usuario.getLogin().equals(principal) && usuario.getPassword().equals(password)) {
            return new UsernamePasswordAuthenticationToken(usuario.getLogin(), usuario.getPassword(), new GrantedAuthorityImpl[]{new GrantedAuthorityImpl("ROLE_USER")});
        } else {
            throw new BadCredentialsException("Usuario / Password incorrecta para" + principal);
        }

    }
}
